﻿using DimensionsHelper.Common.Contracts.Table;
using DimensionsHelper.Services.CsvReader;

namespace DimensionsHelper.Client.WinUi.ViewModels;

public partial class TableReorderMapItemViewModel(TableReorderMapViewModel container, TableReorderMapItemViewModel? parent)
    : ObservableObject
{
    public TableReorderMapItemViewModel? Parent => parent;

    public TableReorderMapViewModel Container => container;

    public bool CanAddChild => Parent == null;

    [ObservableProperty]
    public partial string SourceTableName { get; set; } = string.Empty;

    public ObservableCollection<TableReorderMapItemViewModel> ReorderTables { get; } = [];

    public TableReorderMapItemViewModel AddNew()
    {
        TableReorderMapItemViewModel item = new(Container, this);
        ReorderTables.Add(item);
        return item;
    }

    [RelayCommand]
    private void Add() => AddNew();

    [RelayCommand]
    public void Remove()
    {
        if (Parent != null)
        {
            Parent.ReorderTables.Remove(this);
        }
        else
        {
            Container.Items.Remove(this);
        }
    }
}

public partial class TableReorderMapViewModel : ObservableObject
{
    public ObservableCollection<TableReorderMapItemViewModel> Items { get; } = [];

    public ObservableCollection<string> TableNames { get; } = [];

    [ObservableProperty]
    public partial string SampleFileName { get; set; } = "";


    [ObservableProperty]
    public partial string DisplaySampleFileInfo { get; set; } = "未载入示例表格";


    partial void OnSampleFileNameChanged(string value)
    {
        if (!string.IsNullOrEmpty(value))
        {
            DisplaySampleFileInfo = $"示例表格：{value}";
        }
    }


    [RelayCommand]
    private async Task SelectSampleCsvFile()
    {
        string? fileName = await App.GetService<IFilePikerService>().PickSingleFileAsync(FileFilters.Csv);
        if (string.IsNullOrEmpty(fileName) || fileName.Equals(SampleFileName))
        {
            return;
        }

        TableFormatterTableOptionsViewModel options = App.GetService<TableFormatterTableOptionsViewModel>();
        ITableReader reader = App.GetService<ITableReader>();
        using FileStream stream = File.OpenRead(fileName);
        reader.ReadStream(stream);
        reader.BuildTables(CsvTableRecognizer.Create(
            options.TitleFeature, options.TableEndFeature, options.BaseFeature));
        reader.FinishStream();

        TableNames.Clear();

        foreach (string item in reader.Select(t => t.TitleCell.Text))
        {
            if (!TableNames.Contains(item))
            {
                TableNames.Add(item);
            }
        }

        SampleFileName = fileName;
    }


    [RelayCommand]
    public void Add() => Items.Add(new TableReorderMapItemViewModel(this, null));


    [RelayCommand]
    public void Clear() => Items.Clear();


    public void FromDictionary(Dictionary<string, IEnumerable<string>> source)
    {
        Items.Clear();

        foreach ((string s, IEnumerable<string> targets) in source)
        {
            TableReorderMapItemViewModel item = new(this, null)
            {
                SourceTableName = s
            };

            foreach (string target in targets)
            {
                TableReorderMapItemViewModel subItem = item.AddNew();
                subItem.SourceTableName = target;
            }

            Items.Add(item);
        }
    }


    public void ToDictionary(IDictionary<string, IEnumerable<string>> target)
    {
        target.Clear();

        foreach (TableReorderMapItemViewModel item in Items.Where(i => !string.IsNullOrEmpty(i.SourceTableName)))
        {
            foreach (string reorder in item.ReorderTables.Select(model => model.SourceTableName))
            {
                target.AddOrUpdate(item.SourceTableName,
                    () => new HashSet<string>(),
                    list => ((HashSet<string>)list).Add(reorder.TrimEnd()));
            }
        }
    }
}